package com.example.shangguigu.rsa_ecc;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.security.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @DESCRIPTION: 非对称密码算法学习：SM2 SM9 RSA ECC
 * @USER: shg
 * @DATE: 2023/2/25 14:03
 */
public class RSAAndECCDemo_sgg {

    private static Key privateKey;
    private static Key publicKey;

    static {
        Map<String, Key> rsaPrivateAndPublicKey = null;
        try {
            rsaPrivateAndPublicKey = getRsaPrivateAndPublicKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        privateKey = rsaPrivateAndPublicKey.get("privateKey");
        publicKey = rsaPrivateAndPublicKey.get("publicKey");
    }

    public static void main(String[] args) throws Exception {
        // 获取rsa算法的公钥，私钥
        getRsaPrivateAndPublicKey();

        // 私钥加密
        String rsaEncrypt = RSAEncrypt("硅谷", "RSA");
        System.out.println("RAS私钥加密后的数据："+rsaEncrypt);

        // 私钥解密
        String rsaDecrypt = RSADecrypt(rsaEncrypt,"RSA");
        System.out.println("RAS公钥解密后的数据："+rsaDecrypt);

    }

    /**
     * 获取rsa算法的公钥，私钥
     *
     * @throws Exception
     */
    private static Map<String, Key> getRsaPrivateAndPublicKey() throws Exception {

        Map<String, Key> result = new HashMap<>();

        // 创建密钥对
        KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance("RSA");
        KeyPair keyPair = pairGenerator.generateKeyPair();

        // 获取私钥，公钥
        PrivateKey aPrivate = keyPair.getPrivate();
        PublicKey aPublic = keyPair.getPublic();
        result.put("privateKey", aPrivate);
        result.put("publicKey", aPublic);

        byte[] privateEncoded = aPrivate.getEncoded();
        byte[] publicEncoded = aPublic.getEncoded();

        // String privateKey = Base64.getEncoder().encodeToString(privateEncoded);
        // System.out.println(privateKey);
        //
        // String publicKey = Base64.getEncoder().encodeToString(publicEncoded);
        // System.out.println(publicKey);

        return result;
    }

    /**
     *  RAS的私钥进行加密
     * @param input
     * @param algorithm
     * @return
     * @throws Exception
     */
    private static String RSAEncrypt(String input, String algorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        // 进行加密
        byte[] bytes = cipher.doFinal(input.getBytes());
        return new BASE64Encoder().encode(bytes);
    }

    /**
     * RSA公钥解密
     *
     * @param rsaEncrypt 由RSA私钥加密后，并由Base64编码后的密文
     * @param algorithm  算法
     * @return 密文解密后的明文
     */
    private static String RSADecrypt(String rsaEncrypt, String algorithm) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, publicKey);

        // 解密操作
        byte[] bytes1 = cipher.doFinal(new BASE64Decoder().decodeBuffer(rsaEncrypt));
        return new String(bytes1);
    }
}
